package com.example.video.common.util;

import com.alibaba.fastjson.JSON;
import com.example.video.admin_server.entity.SysRole;
import com.example.video.admin_server.entity.SysUser;
import com.example.video.common.security.SysUserDetails;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.CompressionCodecs;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultClaims;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.*;


/**
 * @author : yj
 */
@Component
public class JWTUtils {
    public static final String USER_INFO = "USER_INFO";

    public static final String ROLES = "ROLES";

    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expiration}")
    private Long access_token_expiration;

    @Value("${jwt.expiration}")
    private Long refresh_token_expiration;

    private final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS256;

    public String initAccessToken(SysUserDetails userDetails){
        Map map = new HashMap();
        map.put(USER_INFO, JSON.toJSONString(userDetails.getSysUser()));
        map.put(ROLES, JSON.toJSONString(userDetails.getRoles()));
        return generateToken(userDetails.getUsername(), map, access_token_expiration);
    }

    private Date generateExpirationDate(long expiration) {
        return new Date(System.currentTimeMillis() + expiration * 1000);
    }

    private String generateToken(String subject, Map<String, Object> claims, long expiration) {
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(new Date())
                .setExpiration(generateExpirationDate(expiration))
                .compressWith(CompressionCodecs.DEFLATE)
                .signWith(SIGNATURE_ALGORITHM, secret)
                .compact();
    }


    public SysUserDetails getUserFromToken(String auth_token) {
        try {
            Claims claims = getClaimsFromToken(auth_token);
            String userInfo =  (String) claims.get(USER_INFO);
            String roles = (String) claims.get(ROLES);
            SysUserDetails userDetails = new SysUserDetails(JSON.parseObject(userInfo, SysUser.class),JSON.parseArray(roles, SysRole.class));
            return userDetails;
        }catch (Exception e){
            e.printStackTrace();
        }
            return null;
    }

    private Claims getClaimsFromToken(String auth_token) {
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(auth_token)
                    .getBody();
        } catch (Exception e) {
            claims = new DefaultClaims();
        }
        return claims;
    }

    public Boolean validateToken(String auth_token) {
        Claims claims = getClaimsFromToken(auth_token);
        Date expiration = claims.getExpiration();
        return !expiration.before(new Date());
    }

    public String getUsernameFromToken(String auth_token) {
        Claims claims = getClaimsFromToken(auth_token);
        return claims.getSubject();
    }
}
